home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Celestin Apprentice 4
/
Apprentice-Release4.iso
/
Source Code
/
Libraries
/
MacTCP Library 1.1
/
ShowMyAddress ƒ
/
Main.c
< prev
next >
Wrap
Text File
|
1995-12-04
|
22KB
|
991 lines
/*
main.c
Main code for ShowMyAddress. This is just a simple program that will display
a Mac's IP address (& possibly it's name?) in a small window.
History:
06/15/95 dn - Created.
12/04/95 dn - Updated for Apprentice 4
*/
// System Includes
#include <MyTCPIncludes.h>
#include <Sound.h>
#include <Icons.h>
// Local Includes
#include "Main.h"
Boolean gQuit,gResolverDone;
short gMacTCP;
IPAddr gOurAddr;
Str255 gOurAddrStr="\punknown";
Str255 gOurIPStr="\p0.0.0.0";
short _gXLoc;
short gXPos,gYPos;
AEEventHandlerUPP gOappUpp,gOdocUpp,gPdocUpp,gQuitUpp;
Handle gErrSnd;
SoundUPP gErrUpp;
char* gAboutTxt[]={
"© 1995 by Dave Nebinger.",
"Some portions © Symantec and Apple.",
" ",
"Just a simple program to show how to",
"get a Mac's IP address and cannonical",
"name using my MacTCP library.",
" ",
NULL
};
// Main Code Entry Point
void main(void){
OSErr err;
err=InitToolbox();
if (err==noErr){
err=Initialize();
if (err==noErr){
err=MainLoop();
}
err=CleanUp();
}
}
// appleevents.h
OSErr InitializeAppleEvents(void){
OSErr err=noErr;
gOappUpp=NewAEEventHandlerProc(HandleOApp);
gOdocUpp=NewAEEventHandlerProc(HandleODoc);
gPdocUpp=NewAEEventHandlerProc(HandlePDoc);
gQuitUpp=NewAEEventHandlerProc(HandleQuit);
err=AEInstallEventHandler(kCoreEventClass,kAEOpenApplication,gOappUpp, 0, FALSE);
if (err!=noErr)
return err;
err=AEInstallEventHandler(kCoreEventClass,kAEOpenDocuments,gOdocUpp, 0, FALSE);
if (err!=noErr)
return err;
err=AEInstallEventHandler(kCoreEventClass,kAEPrintDocuments,gPdocUpp, 0, FALSE);
if (err!=noErr)
return err;
err=AEInstallEventHandler(kCoreEventClass,kAEQuitApplication,gQuitUpp, 0, FALSE);
return err;
}
pascal OSErr HandleOApp(AppleEvent* ae,AppleEvent* reply,long refCon){
OSErr err=noErr;
err=HandleRequiredParams(ae);
if (err==noErr){
// do any open application stuff here.
// nothing to do, it has been done in the initialization routines...
} else
HandleMissedParams(reply);
return err;
}
pascal OSErr HandleODoc(AppleEvent* ae,AppleEvent* reply,long refCon){
OSErr err=noErr;
err=HandleRequiredParams(ae);
if (err==noErr){
// do any open document stuff here...
err=NotHandledEvent(reply);
}
return err;
}
OSErr NotHandledEvent(AppleEvent* ae){
OSErr err;
if (ae->dataHandle!=nil){
Str255 errStr="\pShowMyAddress can't process the event";
err=AEPutParamPtr(ae,keyErrorString,typeChar,(Ptr)&errStr[1],errStr[0]);
}
return errAEEventNotHandled;
}
OSErr HandleMissedParams(AppleEvent* ae){
OSErr err=noErr;
if (ae->dataHandle!=nil){
Str255 errStr="\pRequired parameters were not received";
err=AEPutParamPtr(ae,keyErrorString,typeChar,(Ptr)&errStr[1],errStr[0]);
}
return err;
}
pascal OSErr HandlePDoc(AppleEvent* ae,AppleEvent* reply,long refCon){
OSErr err=noErr;
err=HandleRequiredParams(ae);
if (err==noErr){
// do any print document stuff here
err=NotHandledEvent(reply);
} else
HandleMissedParams(reply);
return err;
}
pascal OSErr HandleQuit(AppleEvent* ae,AppleEvent* reply,long refCon){
OSErr err=noErr;
err=HandleRequiredParams(ae);
if (err==noErr){
// do any error free quit stuff here.
} else
HandleMissedParams(reply);
gQuit=true;
return noErr; // force to noErr because we don't care about errors...
}
OSErr HandleRequiredParams(AppleEvent* ae){
DescType type;
Size size;
OSErr err;
err=AEGetAttributePtr(ae, keyMissedKeywordAttr,typeWildCard, &type,nil, 0, &size);
if (err==errAEDescNotFound){ // you got all the required parameters
err=noErr;
} else {
if (err == noErr) // you missed a required parameter
err=errAEParamMissed;
// else the call to AEGetAttributePtr failed
}
return err;
}
OSErr Initialize(void){
OSErr err=noErr,serr;
Handle mbar;
MenuHandle mh;
// Initialize our application...
// init the globals
gQuit=false;
gMacTCP=-1;
gOurAddr.a.addr=(b_32)0L;
_gXLoc=0; // internal value for controlling where strings are drawn...
gXPos=20;
gYPos=50;
// install our menu bar
mbar=GetNewMBar(kMBar);
SetMenuBar(mbar);
DrawMenuBar();
mh=GetMHandle(kMApple);
AddResMenu(mh,'DRVR');
// get and install the error sound...
gErrSnd=GetResource('snd ',30006);
gErrUpp=NewSoundProc(HandleErrorSound);
if (gErrSnd!=(Handle)0L){
// detach it to keep it around
DetachResource(gErrSnd);
MoveHHi(gErrSnd);
ErrorSound(gErrUpp);
}
// Initialize the apple events...
err=InitializeAppleEvents();
// Initialize TCP & DNR
err=OpenMacTCP(&gMacTCP,false);
if (err==noErr){
// pass null to use the "Hosts" file in the system folder
err=OpenResolver((StringPtr)NULL);
if (err==noErr){
// Have the resolver, now get our address...
GetAddrParamBlock* ip;
ip=NewGetIPParmBlkPtr();
ip->ioCRefNum=gMacTCP; // the TCP driver refnum global...
// get our ip address
err=GetMyIPAddr(ip,FALSE); // do it sync...
if (err!=noErr){
// Sometimes it can return an error, but it can be ignored
// if the ioResult field for the IP parm block is noErr.
// check the ioResult to be sure...
err=ip->ioResult;
}
if (err==noErr){
HostInfoUPP hiupp;
HostInfo hinfo;
// set our address now
gOurAddr.a.addr=ip->ourAddress;
// convert it to a string...
AddrToStr(ip->ourAddress,(char*)gOurIPStr);
c2pstr((char*)gOurIPStr);
// we have our address, now get our string address...
gResolverDone=false;
hiupp=NewHostInfoProc(ResolverDone);
err=AddrToName(ip->ourAddress,&hinfo,hiupp,(char*)0);
if (err==cacheFault){
// then the resolver is checking with the name server, must wait
// for the reply...
if (!gResolverDone){
while (!gResolverDone){
/* Do Nothing Here */
;
}
}
}
// we are now done with the AddrToName call...
DisposeHostInfoProc(hiupp);
if (hinfo.rtnCode==(long)noErr){
// no error fetching the name, use it...
c2pstr(hinfo.cname);
BlockMoveData((Ptr)hinfo.cname,(Ptr)gOurAddrStr,hinfo.cname[0] MenuEnabling();
ms=MenuSelect(lpt);
err=HandleMenu(ms);
break;
case inDesk:
case inSysWindow:
SystemClick(erp,wind);
break;
case inContent:
SelectWindow(wind);
break;
case inDrag:
{
Rect br;
BlockMoveData((Ptr)(&qd.screenBits.bounds),(Ptr)&br,sizeof(Rect));
InsetRect(&br,4,4);
DragWindow(wind,pt,&br);
}
break;
case inGoAway:
// we shouldn't get these...
DisposeWindow(wind);
break;
case inZoomIn:
case inZoomOut:
{
Boolean sel=true;
if (erp->modifiers & cmdKey)
sel=false; // don't select if the cmd key is down
ZoomWindow(wind,part,sel);
}
break;
default:
// some weird part was clicked
// we ignore it...
break;
}
return err;
}
OSErr HandleMenuEnabling(void){
OSErr err=noErr;
WindowPtr wind;
Boolean closeEnabled=true;
MenuHandle mh;
wind=FrontWindow();
mh=GetMHandle(kMFile);
if (wind==(WindowPtr)0L){
// there are no active windows to close
DisableItem(mh,kMClose);
// reset the window offsets to start at the upper-left position on the screen
gXPos=20;
gYPos=50;
} else {
// there are active windows to close
EnableItem(mh,kMClose);
}
return err;
}
OSErr HandleMenu(long ms){
OSErr err=noErr;
short menu,item;
menu=HiWord(ms);
item=LoWord(ms);
if (menu!=0){
// a valid menu choice
switch (menu){
case kMApple:
err=HandleApple(item);
break;
case kMFile:
err=HandleFile(item);
break;
case kMEdit:
err=HandleEdit(item);
break;
default:
// could be an error, but I am ignoring them...
break;
}
} else {
ms=MenuChoice();
// ms represents a disabled choice the user picked.
}
HiliteMenu(0);
return err;
}
pascal void HandleErrorSound(short var){
if (var!=0){
HLock(gErrSnd);
// play the sound synchronously...
(void)SndPlay((SndChannelPtr)0L,(SndListHandle)gErrSnd,FALSE);
HUnlock(gErrSnd);
}
}
OSErr HandleError(StringPtr errStr,OSErr err){
OSErr ierr=noErr;
Str255 numErr;
long lerr;
// build the error number string
lerr=(long)err;
NumToString(lerr,numErr);
// have paramtext fill in the alert
ParamText(errStr,numErr,"\p","\p");
// let stopalert display the error message.
StopAlert(30006,(ModalFilterUPP)0L);
return ierr;
}
OSErr HandleApple(short item){
OSErr err=noErr;
switch (item){
case kMAbout:
err=HandleAbout();
break;
default:
// handle da's here
{
MenuHandle mh=GetMHandle(kMApple);
Str255 da;
GrafPtr savePort;
GetItem(mh,item,da);
GetPort(&savePort);
OpenDeskAcc(da);
SetPort(savePort);
}
break;
}
return err;
}
OSErr HandleFile(short item){
OSErr err=noErr;
switch (item){
case kMNew:
err=NewSAWindow();
break;
case kMOpen:
// we shouldn't get one of these...
break;
case kMClose:
{
WindowPtr wind;
WindowPeek wp;
WindowPtr next;
wind=FrontWindow();
if (wind!=(WindowPtr)0L){
wp=(WindowPeek)wind;
next=(WindowPtr)wp->nextWindow;
if (wp->windowKind<0){
// a desk acc window
CloseDeskAcc(wp->windowKind);
} else {
// a regular window
DisposeWindow(wind);
}
if (next!=(WindowPtr)0L)
SelectWindow(next);
}
}
break;
case kMQuit:
gQuit=true;
break;
default:
break;
}
return err;
}
OSErr HandleEdit(short item){
OSErr err=noErr;
// This application doesn't use any editing features so they
// are being ignored...
return err;
}
// use this routine to handle key events.
OSErr HandleKey(EventRecord* erp){
OSErr err=noErr;
char ch,key;
long mk;
ch=erp->message&charCodeMask;
key=(erp->message&keyCodeMask)>>8;
if (erp->modifiers & cmdKey){
// menu event
err=HandleMenuEnabling();
mk=MenuKey(ch);
err=HandleMenu(mk);
} else {
// normal key events
// currently ignored
}
return err;
}
// Handle window activate events here
OSErr HandleActivateEvt(EventRecord* erp){
OSErr err=noErr;
WindowPtr wind;
wind=(WindowPtr)erp->message;
if (wind==(WindowPtr)0L)
return noErr;
if (erp->modifiers&activeFlag){
BringToFront(wind); // make it the frontmost
HiliteWindow(wind,true); // activate the window...
} else {
HiliteWindow(wind,false); // deactivate the window...
}
return err;
}
// Handle Window Updates
OSErr HandleUpdate(EventRecord* erp){
OSErr err=noErr;
WindowPtr wind;
wind=(WindowPtr)erp->message;
BeginUpdate(wind);
DrawSAWindow(wind);
EndUpdate(wind);
return err;
}
// Handle Disk Events here...
OSErr HandleDisk(EventRecord* erp){
OSErr err=noErr;
Point pt;
SetPt(&pt,100,100);
err=(OSErr)DIBadMount(pt,erp->message);
return err;
}
// Entry point for Apple Event Handling
OSErr HandleHighLevelEvent(EventRecord* erp){
OSErr err=noErr;
err=AEProcessAppleEvent(erp);
return err;
}
// use this routine to handle activate events...
OSErr HandleActivate(EventRecord* erp){
OSErr err=noErr;
WindowPtr wind;
wind=FrontWindow();
if (wind!=(WindowPtr)0L)
HiliteWindow(wind,true); // hilite the window
return err;
}
// use this routine to handle the deactivate events
OSErr HandleDeactivate(EventRecord* erp){
OSErr err=noErr;
WindowPtr wind;
wind=FrontWindow();
if (wind!=(WindowPtr)0L)
HiliteWindow(wind,false); // deactivate the window
return err;
}
// use this routine to change the mouse cursor depending on where the mouse is located.
OSErr HandleMouseMoved(EventRecord* erp){
OSErr err=noErr;
return err;
}
// Get and display a new ShowAddressWindow
OSErr NewSAWindow(void){
OSErr err=noErr;
WindowPtr wind;
short wwid,whei;
wind=GetNewCWindow(kWWindow,kWindNoStorage,kWindInFront);
if (wind!=(WindowPtr)0L){
// move the window into it's new position...
MoveWindow(wind,gXPos,gYPos,true);
ShowWindow(wind);
wwid=wind->portRect.right-wind->portRect.left;
whei=wind->portRect.bottom-wind->portRect.top;
gXPos+=15;
gYPos+=30;
if (gXPos+wwid+10>qd.screenBits.bounds.right){
gXPos=20;
gYPos=50;
}
if (gYPos+whei+10>qd.screenBits.bounds.bottom)
gYPos=50;
err=DrawSAWindow(wind);
} else {
err=ResError();
}
return err;
}
OSErr DrawSAWindow(WindowPtr wind){
OSErr err=noErr;
GrafPtr savePort;
if (wind!=(WindowPtr)0L){
// set the port to the new window (just to be sure)...
GetPort(&savePort);
SetPort((GrafPtr)wind);
// now set up the font stuff
TextFont(geneva);
TextFace(normal);
TextSize(9);
TextMode(srcOr);
TextFace(bold);
MoveTo(5,13);
DrawString("\pIP Address:");
MoveTo(5,26);
DrawString("\pCanonical Name:");
if (_gXLoc==0) // calculate _gXLoc once given the current font, size, and face...
_gXLoc=5+StringWidth("\pCanonical Name:") + 6;
TextFace(normal);
MoveTo(_gXLoc,13);
DrawString(gOurIPStr);
MoveTo(_gXLoc,26);
DrawString(gOurAddrStr);
SetPort(savePort);
}
return err;
}
// Initialize the Mac Toolbox
OSErr InitToolbox(void){
OSErr err=noErr;
InitGraf((Ptr) &qd.thePort);
InitFonts();
InitWindows();
InitMenus();
FlushEvents(everyEvent,0);
TEInit();
InitDialogs(0L);
InitCursor();
return err;
}
OSErr HandleAbout(void){
OSErr err=noErr;
DialogPtr dlg;
short i;
Rect r;
Handle h;
UserItemUPP frame,icons,box,txt;
ModalFilterUPP custom;
GrafPtr savePort;
short itemHit;
GetPort(&savePort);
dlg=GetNewDialog(128,kWindNoStorage,kWindInFront);
if (dlg!=(DialogPtr)0L){
// use the dialog
SetPort((GrafPtr)dlg);
// first frame the ok button...
GetDItem(dlg,5,&i,&h,&r);
frame=NewUserItemProc(ItemOvalFrame);
SetDItem(dlg,5,i,(Handle)frame,&r);
// now do the icon family...
GetDItem(dlg,2,&i,&h,&r);
icons=NewUserItemProc(ItemIconFamily);
SetDItem(dlg,2,i,(Handle)icons,&r);
// and the 3d outline
GetDItem(dlg,3,&i,&h,&r);
box=NewUserItemProc(Item3DBox);
SetDItem(dlg,3,i,(Handle)box,&r);
// and the text
GetDItem(dlg,4,&i,&h,&r);
txt=NewUserItemProc(ItemAboutText);
SetDItem(dlg,4,i,(Handle)txt,&r);
itemHit=3;
custom=NewModalFilterProc(CustomFilter);
ShowWindow((WindowPtr)dlg);
while (itemHit!=1){ // while not the ok button
ModalDialog(custom,&itemHit);
switch (itemHit){
case 2: // icon family
// play the beavis sound...
break;
default:
// do nothing special
break;
}
}
DisposeDialog(dlg);
DisposeRoutineDescriptor(custom);
DisposeRoutineDescriptor(frame);
DisposeRoutineDescriptor(icons);
DisposeRoutineDescriptor(txt);
DisposeRoutineDescriptor(box);
} else {
err=ResError();
}
SetPort(savePort);
return err;
}
pascal void ItemOvalFrame(WindowPtr wind,short item){
DialogPtr dlg;
short i;
Rect r;
Handle h;
dlg=(DialogPtr)wind;
GetDItem(dlg,item,&i,&h,&r);
PenSize(2,2);
FrameRoundRect(&r,8,8);
PenNormal();
}
pascal void ItemAboutText(WindowPtr wind,short item){
DialogPtr dlg;
short i;
Rect r;
Handle h;
short sw;
short hz,w,x,y,z;
RgnHandle clip;
register char* cp;
char** cpp;
short slen;
clip=NewRgn();
GetClip(clip);
dlg=(DialogPtr)wind;
GetDItem(dlg,item,&i,&h,&r);
// first draw the header
TextFont(times);
TextFace(normal);
TextSize(14);
sw=StringWidth("\pShowMyAddress");
w=(r.right-r.left); // width of the text box
hz=(r.bottom-r.top);// height of the text box
MoveTo(r.left+(w/2)-(sw/2),18+r.top);
DrawString("\pShowMyAddress");
r.top+=20;
ClipRect(&r);
z=0;
cpp=gAboutTxt;
TextFont(geneva);
TextSize(9);
TextFace(normal);
while (*cpp!=NULL){
// calculate the length of the text
slen=0;
cp=*cpp;
while (*cp){
cp++;
slen++;
}
MoveTo(r.left+2,r.top+(12*(z+1)));
DrawText(*cpp,0,slen);
cpp++;
z++;
}
SetClip(clip);
DisposeRgn(clip);
}
#define kDarkValue 10000
#define kLightValue 63000
pascal void Item3DBox(WindowPtr wind,short item){
DialogPtr dlg;
short i;
Rect r;
Handle h;
RGBColor ltg,dkg;
RGBColor save;
GetForeColor(&save);
dlg=(DialogPtr)wind;
GetDItem(dlg,item,&i,&h,&r);
PenNormal();
PenSize(2,2);
ltg.red=kLightValue;
ltg.green=kLightValue;
ltg.blue=kLightValue;
dkg.red=kDarkValue;
dkg.green=kDarkValue;
dkg.blue=kDarkValue;
RGBForeColor(<g);
MoveTo(r.left,r.bottom);
LineTo(r.left,r.top);
LineTo(r.right,r.top);
RGBForeColor(&dkg);
LineTo(r.right,r.bottom);
LineTo(r.left+2,r.bottom);
PenNormal();
RGBForeColor(&save);
}
pascal void ItemIconFamily(WindowPtr wind,short item){
DialogPtr dlg;
short i;
Rect r;
Handle h;
dlg=(DialogPtr)wind;
GetDItem(dlg,item,&i,&h,&r);
PlotIconID(&r,atVerticalCenter+atHorizontalCenter,ttNone,128);
}
pascal Boolean CustomFilter(DialogPtr dlg,EventRecord* erp,short* item){
Boolean hand=false;
GrafPtr saved;
short part;
GetPort(&saved);
SetPort((GrafPtr)dlg);
switch (erp->what){
case keyDown:
case autoKey:
switch ((erp->message)&charCodeMask){
case 0x0d: // return key
case 0x03: // enter key
case 0x1b: // escape key
*item=1;
hand=true;
break;
case 'c':
case 'C':
case 'o':
case 'O':
case 'w':
case 'W': // look for the command key...
if (erp->modifiers&cmdKey){
// hit command-w
*item=1;
hand=true;
}
break;
}
break;
case mouseDown:
HandleLimitedMouse(erp,&part,&hand);
break;
case updateEvt:
{
WindowPtr wind=(WindowPtr)erp->message;
if ((wind!=(WindowPtr)0)&&((DialogPtr)(wind)!=dlg)){
// got an update event for a background window!
// By calling BeginUpdate/EndUpdate, the update events will stop coming to us.
BeginUpdate(wind);
// call the window's drawing procedure here...
DrawSAWindow(wind);
EndUpdate(wind);
}
}
break;
default:
// do nothing special
break;
}
SetPort(saved);
return hand;
}